import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:io';
import 'package:http/io_client.dart';
import 'CookieManager.dart';

typedef SuccessCallback = void Function(dynamic data);
typedef FailureCallback = void Function(String error);

class NetworkManager {
  static final NetworkManager _instance = NetworkManager._internal();

  factory NetworkManager() {
    return _instance;
  }

  NetworkManager._internal();

  http.Client _createHttpClient() {
    final proxy = 'PROXY 192.168.2.103:8888';
    final ioClient = HttpClient();
    // ioClient.findProxy = (uri) {
    //   return proxy;
    // };
    // ioClient.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
    return IOClient(ioClient);
  }

  Future<void> get(String url, Map<String, String> params, SuccessCallback successCallback, FailureCallback failureCallback) async {
    final uri = Uri.parse(url).replace(queryParameters: params);
    final client = _createHttpClient();
    final response = await client.get(uri, headers: {
      'Cookie': CookieManager().cookies.entries.map((e) => '${e.key}=${e.value}').join('; ')
    });
    CookieManager().setCookies(response);
    if (response.statusCode == 200) {
      successCallback(json.decode(response.body));
    } else {
      failureCallback('Error: ${response.statusCode}, ${response.body}');
    }
  }

  Future<void> post(String url, Map<String, String> params, SuccessCallback successCallback, FailureCallback failureCallback) async {
    final uri = Uri.parse(url);
    final client = _createHttpClient();
    try {
      final response = await client.post(uri, body: params, headers: {
        'Cookie': CookieManager().cookies.entries.map((e) => '${e.key}=${e.value}').join('; ')
      });
      CookieManager().setCookies(response);
      if (response.statusCode == 200) {
        successCallback(json.decode(response.body));
      } else {
        failureCallback('Error: ${response.statusCode}, ${response.body}');
      }
    } catch (e) {
      failureCallback(e.toString());
    }
  }

  Future<void> put(String url, Map<String, String> params, SuccessCallback successCallback, FailureCallback failureCallback) async {
    final uri = Uri.parse(url);
    final client = _createHttpClient();
    try {
      final response = await client.put(uri, body: params, headers: {
        'Cookie': CookieManager().cookies.entries.map((e) => '${e.key}=${e.value}').join('; ')
      });
      CookieManager().setCookies(response);
      if (response.statusCode == 200) {
        successCallback(json.decode(response.body));
      } else {
        failureCallback('Error: ${response.statusCode}, ${response.body}');
      }
    } catch (e) {
      failureCallback(e.toString());
    }
  }

  Future<void> delete(String url, Map<String, String> params, SuccessCallback successCallback, FailureCallback failureCallback) async {
    final uri = Uri.parse(url).replace(queryParameters: params);
    final client = _createHttpClient();
    try {
      final response = await client.delete(uri, headers: {
        'Cookie': CookieManager().cookies.entries.map((e) => '${e.key}=${e.value}').join('; ')
      });
      CookieManager().setCookies(response);
      if (response.statusCode == 200) {
        successCallback(json.decode(response.body));
      } else {
        failureCallback('Error: ${response.statusCode}, ${response.body}');
      }
    } catch (e) {
      failureCallback(e.toString());
    }
  }
}